package han.fetch;

import com.han.http.client.paramter.RequestHeader;
import han.entity.InvestBasicEntity;
import han.entity.InvestCompanyIdEntity;
import han.entity.InvestCompanyInfoEntity;
import han.exception.MuchRequestException;
import han.exception.NoneCompanyIdException;
import han.exception.UnLoginException;
import han.parser.InvestOrganizationInfoParser;
import han.proof.Cookie;
import han.sql.InsertThread;

import java.util.List;
import java.util.Random;

import static com.han.http.util.Print.printlnErr;
import static com.han.http.util.Print.printlnInfo;

/**
 * @author: Han
 * @date: 2018/8/6 14:31
 * @dscription: 抓取投资机构线程
 */
public class InvestOrganizationInfoThread implements Runnable {

    /**
     * 同步锁
     */
    private final Object krLock;
    /**
     * 抓取对象
     */
    private Fetcher fetcher;
    /**
     * cookie
     */
    private Cookie cookie;
    /**
     * id list
     */
    private List<InvestCompanyIdEntity> idList;
    private InsertThread insertThread;

    InvestOrganizationInfoThread(List<InvestCompanyIdEntity> idList, Object krLock, Cookie cookie, InsertThread insertThread) {
        this.insertThread = insertThread;
        fetcher = new Fetcher();
        this.cookie = cookie;
        this.krLock = krLock;
        this.idList = idList;
    }

    @Override
    public void run() {
        getInfo();
    }


    private void getInfo() {
        Random random = new Random();
        int interval;
        for (int i = 0; i < idList.size(); i++) {
            if (cookie.getStatus() != 0) {
                //如果cookie不可用,跳出
                printlnInfo(cookie.getLoginName() + "不可用");
                break;
            }
            //休眠时间
            interval = random.nextInt(1000 * 5) + 1000 * 5;
            //id实体
            InvestCompanyIdEntity idEntity = idList.get(i);
            String krId = idEntity.getCompanyId();
            try {
                //同步锁,避免同时发出大量请求
                InvestCompanyInfoEntity infoEntity = getInfoById(idEntity);
                printlnInfo(idEntity.getCompanyId() + "已抓取完成,即将休眠" + interval + "毫秒," + i);
                insertThread.insertInsertOrgInfo(infoEntity);
            } catch (MuchRequestException e) {
                printlnErr(cookie.getLoginName() + ":Cookie被封");
                cookie.setStatus(1);
            } catch (NoneCompanyIdException e) {
                printlnErr(cookie.getLoginName() + ":该公司不存在," + krId);
            } catch (UnLoginException e) {
                printlnInfo(cookie.getLoginName() + ":可能被永久封禁了");
                cookie.setStatus(2);
            } catch (Exception e) {
                printlnErr(cookie.getLoginName() + ":未知错误," + e.getMessage() + "," + krId);
                e.printStackTrace();
            } finally {
                //不管成功或者失败,均休眠
                try {
                    Thread.sleep(interval);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取投资机构信息
     *
     * @param idEntity id
     * @return 投资机构
     * @throws MuchRequestException   请求太多,被暂封了
     * @throws NoneCompanyIdException 没有这个id
     * @throws UnLoginException       cookie失效,或者账号被永久封了
     */
    private InvestCompanyInfoEntity getInfoById(InvestCompanyIdEntity idEntity) throws
            MuchRequestException, NoneCompanyIdException, UnLoginException {

        RequestHeader[] requestHeaders = {
                new RequestHeader("Host", "rong.36kr.com"),
                new RequestHeader("Connection", "keep-alive"),
                new RequestHeader("Accept", "application/json, text/plain, */*"),
                new RequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"),
                new RequestHeader("X-Tingyun-Id", "Dio1ZtdC5G4;r=74955202"),
                new RequestHeader("Referer", "https://rong.36kr.com/org/list&?industry=10&page=2"),
                new RequestHeader("Accept-Encoding", "gzip, deflate, br"),
                new RequestHeader("Accept-Language", "zh-CN,zh;q=0.9"),
                new RequestHeader("Cookie", cookie.getCookie())
        };
        String krId = idEntity.getCompanyId();
        String rowUrlStr = "https://rong.36kr.com/n/api/org/" + krId;
        String[] usedUrls = {
                rowUrlStr + "/basic",
                rowUrlStr + "/member"
        };
        Random random = new Random();
        int interval;
        InvestCompanyInfoEntity entity = new InvestCompanyInfoEntity();
        for (int i = 0; i < usedUrls.length; i++) {
            String usedUrl = usedUrls[i];
            interval = random.nextInt(1000 * 5) + 1000 * 5;
            try {
                String page;
                synchronized (krLock) {
                    //同步锁,避免同时发出大量请求
                    page = fetcher.getInfoByGet(usedUrl, requestHeaders, 1000 * 10, 1000 * 10, null);
                    page = page.replaceAll("[\\s]*", "");
                    //额外休眠100毫秒
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果账号被暂时封禁,抛出异常
                if (page.contains("您请求的过于频繁，请稍后再试")) {
                    throw new MuchRequestException();
                }
                if (page.contains("公司不存在")) {
                    throw new NoneCompanyIdException();
                }
                //如果cookie失效,可能登录期限已过或者账号被永久封禁
                if (page.contains("用户未登录")) {
                    throw new UnLoginException();
                }
                if (i == 0) {
                    InvestBasicEntity investBasicEntity = InvestOrganizationInfoParser.getBasic(page);
                    entity.setBasicInfo(investBasicEntity);
                    printlnInfo(cookie.getLoginName() + ":" + krId + "基础信息已抓取完成,即将休眠" + interval + "毫秒");
                } else {
                    String member = InvestOrganizationInfoParser.getMember(page);
                    entity.setMember(member);
                    printlnInfo(cookie.getLoginName() + ":" + krId + "成员信息已抓取完成,即将休眠" + interval + "毫秒");
                }
            } catch (MuchRequestException | NoneCompanyIdException | UnLoginException e) {
                throw e;
            } catch (Exception e) {
                printlnErr(cookie.getLoginName() + ":" + krId + ":" + usedUrl + "解析失败" + e.getMessage());
            } finally {
                try {
                    Thread.sleep(interval);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return entity;
    }

    /*private void getOrgInfo() {

        Random random = new Random();
        InfoSupplementer infoSupplementer = new InfoSupplementer();
        int requestCount = 0;
        for (FinanceProjectIdEntity idEntity : idList) {

            if (cookie.getStatus() != 0) {
                //如果cookie不可用,跳出
                printlnInfo(cookie.getLoginName() + "不可用");
                break;
            }
            //获取投资机构id
            String orgId = idEntity.getProjectId();
            //获取随机间隔
            int interval = random.nextInt(1000 * 5) + 1000 * 5;
            try {
                //访问目标项目,获取项目信息
                InvestCompanyInfoEntity infoEntity;
                infoEntity = getOrgInfoM(orgId);
                String name = infoEntity.getFullName();
                if (name.isEmpty()) {
                    name = infoEntity.getName();
                }
                //访问企查查,获取联系方式
                String[] contacts;
                synchronized (qiChaChaLock) {
                    try {
                        Thread.sleep(random.nextInt(1000 * 5) + 1000 * 5);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //同步锁,避免同时发出大量并发请求
                    contacts = infoSupplementer.qiChaCha(name, "hasShow=1; PHPSESSID=33ffeupoe08co0mvoekgcn75p1; zg_did=%7B%22did%22%3A%20%22164fdd36f92880-0357b3be767f87-5701f32-1fa400-164fdd36f935ea%22%7D; UM_distinctid=164fdd36fa459e-0b35ccc276d6bd-5701f32-1fa400-164fdd36fa518f; CNZZDATA1254842228=1093813720-1533265290-%7C1533265290; Hm_lvt_3456bee468c83cc63fb5147f119f1075=1533266850; _uab_collina=153326687412306702523011; acw_tc=AQAAAK3uQWalBw0ALpoHJBnXmgdZsZ26; _umdata=486B7B12C6AA95F218108B1607B61F34830166FF0C746B3B83F5AA11FCA564CC538BAB643119F39BCD43AD3E795C914C90A4697A7417736DFCFD3D5D355C8971; Hm_lpvt_3456bee468c83cc63fb5147f119f1075=1533266897; zg_de1d1a35bfa24ce29bbf2c7eb17e6c4f=%7B%22sid%22%3A%201533266849687%2C%22updated%22%3A%201533266909603%2C%22info%22%3A%201533266849693%2C%22superProperty%22%3A%20%22%7B%7D%22%2C%22platform%22%3A%20%22%7B%7D%22%2C%22utm%22%3A%20%22%7B%7D%22%2C%22referrerDomain%22%3A%20%22%22%2C%22cuid%22%3A%20%22a55d2ba70f4d70ac8c20b6288d6443c0%22%7D");
                }
                infoEntity.setEmail(contacts[0]);
                infoEntity.setPhoneNumber(contacts[1]);
                infoEntity.setAddress(contacts[2]);
                //更新数据库
                operator.updateInvestCompanyInfo(infoEntity);
                requestCount++;
                printlnInfo(cookie.getLoginName() + ":" + orgId + "抓取成功,已抓取" + requestCount);
            } catch (MuchRequestException e) {
                printlnErr(cookie.getLoginName() + ":Cookie被暂时封了:");
                cookie.setStatus(2);
            } catch (NoneCompanyIdException e) {
                printlnErr(cookie.getLoginName() + ":没有该项目:" + idEntity.getProjectId());
            } catch (OtherDeviceLoginException e) {
                printlnInfo(cookie.getLoginName() + "你的账号已在其他设备登录:");
                cookie.setStatus(3);
            } catch (Exception e) {
                printlnErr(cookie.getLoginName() + "未知错误");
                e.printStackTrace();
            } finally {
                //不管成功或者失败,均休眠
                try {
                    Thread.sleep(interval);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private InvestCompanyInfoEntity getOrgInfoM(String orgId) throws NoneCompanyIdException, MuchRequestException
            , OtherDeviceLoginException, OtherException {

        String urlStr = "https://rong.36kr.com/api/mobi-investor/v3/company/" + orgId + "?statsRefer=others";
        RequestHeader[] requestHeaders = {
                new RequestHeader("User-Agent", "36kr-Tou-Android/4.1.2 (MI 6; Android 8.0.0; Scale/1920x1080)"),
                new RequestHeader("Cookie", cookie.getCookie()),
                new RequestHeader("Host", "rong.36kr.com"),
                new RequestHeader("Connection", "Keep-Alive"),
                new RequestHeader("Accept-Encoding", "gzip"),
        };
        int generalTimeout = 1000 * 10;
        InvestCompanyInfoEntity entity = new InvestCompanyInfoEntity();

        try {
            String jsonStr = fetcher.getInfoByGet(urlStr, requestHeaders, generalTimeout, generalTimeout, null);
            if (jsonStr.contains(FinanceProjectId.RESPONSE_CODE[3])) {
                throw new NoneCompanyIdException();
            } else if (jsonStr.contains(FinanceProjectId.RESPONSE_CODE[2])) {
                throw new MuchRequestException();
            } else if (jsonStr.contains(FinanceProjectId.RESPONSE_CODE[4])) {
                throw new OtherDeviceLoginException();
            } else if (!jsonStr.contains(FinanceProjectId
                    .RESPONSE_CODE[0])) {
                throw new OtherException("没有获取到数据" + jsonStr + ",项目id" + orgId);
            }
            //entity = FinanceProjectInfoParser.getProjectInfoM(jsonStr);
            //移动端url获取到的数据
            entity.setM(1);
        } catch (IOException | RequestNotExecutedException e) {
            e.printStackTrace();
        }

        return entity;
    }*/
}
